package net.lesscoding.handler;

import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import net.lesscoding.protocol.ProtocolFrameDecoder;
import net.lesscoding.protocol.SharedMessageCodec;
import net.lesscoding.server.handler.*;

/**
 * @author eleven
 * @date 2024/10/31 10:40
 * @apiNote
 */
@Slf4j
@Data
@AllArgsConstructor
public class ChatServerChannelInitializer extends ChannelInitializer<SocketChannel> {

    private LoggingHandler loggingHandler;

    @Override
    protected void initChannel(SocketChannel channel) throws Exception {
        LoginRequestMessageHandler loginRequestMessageHandler = new LoginRequestMessageHandler();
        ChatRequestMessageHandler chatRequestMessageHandler = new ChatRequestMessageHandler();
        GroupCreateRequestMessageHandler groupCreateRequestMessageHandler = new GroupCreateRequestMessageHandler();
        GroupJoinRequestMessageHandler groupJoinRequestMessageHandler = new GroupJoinRequestMessageHandler();
        GroupChatRequestMessageHandler groupChatRequestMessageHandler = new GroupChatRequestMessageHandler();
        GroupQuitRequestMessageHandler groupQuitRequestMessageHandler = new GroupQuitRequestMessageHandler();
        GroupMemberRequestMessageHandler groupMemberRequestMessageHandler = new GroupMemberRequestMessageHandler();
        QuitHandler quitHandler = new QuitHandler();
        channel.pipeline()
                // 用来判断是不是空闲时间过长 或者 写时间过长
                /**
                 * 5s 读时间过长 触发IdleStateHandler.READER_IDLE_EVENT
                 * 5s 写时间过长 触发IdleStateHandler.WRITER_IDLE_EVENT
                 * 60s 读写时间过长 触发IdleStateHandler.ALL_IDLE_EVENT
                 */
                .addLast(new IdleStateHandler(5,5,60))
                // ChannelDuplexHandler 可以同时作为入站处理器和出站处理器
                .addLast(new ChannelDuplexHandler() {

                  @Override
                  public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
                      IdleStateEvent event = (IdleStateEvent)evt;
                      // 触发了读空闲事件
                      if (event.state() == IdleState.READER_IDLE) {
                          log.debug("已经5s没有读到数据了");
                          ctx.channel().close();
                      }
                  }
                })
                .addLast(loggingHandler)
                .addLast(new ProtocolFrameDecoder())
                .addLast(new SharedMessageCodec())
                // 登录处理器
                .addLast(loginRequestMessageHandler)
                // 单聊处理器
                .addLast(chatRequestMessageHandler)
                // 创建群聊处理器
                .addLast(groupCreateRequestMessageHandler)
                // 加入群聊处理器
                .addLast(groupJoinRequestMessageHandler)
                // 群聊处理器
                .addLast(groupChatRequestMessageHandler)
                // 退出群聊处理器
                .addLast(groupQuitRequestMessageHandler)
                // 群聊成员处理器
                .addLast(groupMemberRequestMessageHandler)
                .addLast(quitHandler)

        ;
    }
}
